import os
import time
from ui_window.MainWindow import Ui_MainWindow
from tool.openfile import OpenFile
from tool.mytablewidget import MyTableWidget
from ui_window.select_model import childWinSelectModel
from ui_window.set_param import childWinSetParam
from ui_window.plane_param import childWinSetplane
from PyQt5.QtWidgets import QMainWindow, QWidget, QVBoxLayout, QFileDialog, QAbstractItemView, QLabel,\
                            QTableWidgetItem, QScrollArea, QMessageBox
from PyQt5.QtGui import QIcon
from PyQt5.QtCore import QDir, Qt, QProcess, QFile, QFileInfo
from tool.get_set_file import pid_file, search_file, remove_file, cid_file
import icon


class MyApp(QMainWindow):
    def __init__(self):
        super().__init__()
        self.ui = Ui_MainWindow()
        self.ui.setupUi(self)

        self.index_map = {}
        self.model_list = None
        self.param_list = None
        self.plane_list = None

        self.ui.pushButton_6.clicked.connect(self.click_run_pid)
        self.ui.pushButton.clicked.connect(self.click_input_file)
        self.ui.show_tabWidget.tabCloseRequested.connect(self.click_close_tab)
        self.ui.work_space.tableWidget.cellDoubleClicked.connect(self.click_double_item)
        self.ui.pushButton_4.clicked.connect(self.click_set_param)
        self.ui.pushButton_5.clicked.connect(self.click_select_model)
        self.ui.pushButton_7.clicked.connect(self.click_set_plane)
        self.ui.pushButton_8.clicked.connect(self.click_run_cid)
        self.ui.treeview.doubleClicked.connect(self.load_file)

    def load_file(self, index):
        item_count = self.ui.work_space.item_count
        if item_count <= 0:
            return None
        file_path = self.ui.model.filePath(index)
        file_name = file_path.split('/')[-1]
        text = None
        file_info = QFileInfo(file_path)
        if file_info.isDir():
            return None
        if file_path:
            with open(file_path, 'r') as file:
                text = file.read()

            self.text_tab = QWidget()
            self.text_layout = QVBoxLayout(self.text_tab)
            text_lab = QLabel(self.text_tab)
            text_lab.setText(text)
            text_lab.adjustSize()
            scroll_area = QScrollArea()
            scroll_area.setWidget(text_lab)
            scroll_area.setVerticalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
            scroll_area.setHorizontalScrollBarPolicy(Qt.ScrollBarAlwaysOn)
            self.text_layout.addWidget(scroll_area)
            self.ui.show_tabWidget.addTab(self.text_tab, file_name)

    def click_double_item(self, row, col):
        data_info = self.ui.work_space.item_storage[row]
        is_displaying = data_info.is_displaying
        if not is_displaying:
            self.display_data(data_info)
            tab_count = self.ui.show_tabWidget.count() - 1
            self.index_map[tab_count] = row
            data_info.display_number = tab_count
            data_info.is_displaying = True
        else:
            display_number = data_info.display_number
            self.ui.show_tabWidget.setCurrentIndex(display_number)

    def click_close_tab(self, index):
        if index in self.index_map:
            self.update_map(index)
            self.ui.work_space.update_index(index)
        self.ui.show_tabWidget.removeTab(index)  # 关闭索引对应的tab

    def update_map(self, index):
        self.index_map.pop(index)
        count = len(self.index_map)
        if count > 0:
            keys = [int(i) for i in self.index_map.keys()]
            for i in keys:
                if i > index:
                    self.index_map[i-1] = self.index_map[i]

    def click_run_pid(self):
        item_count = self.ui.work_space.item_count
        current_tab = self.ui.show_tabWidget.currentIndex()
        if item_count > 0:
            if current_tab < 0:
                QMessageBox.warning(self, "Warning!", "请先双击工作区数据\n显示在界面中！",
                                              QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
                return None
            if current_tab in self.index_map:
                if self.param_list is not None and self.model_list is not None:
                    exe_path = os.getcwd() + "\\AeroPID_OEML_RUS.exe"
                    file_path = os.getcwd() + "\\AeroPid_in.dat"
                    # 生成中间的设置文件并放到和exe同级的目录
                    pid_file(self.model_list, self.param_list, file_path)
                    tab_index = self.ui.show_tabWidget.currentIndex()
                    item_index = self.index_map[tab_index]
                    source_path = self.ui.work_space.item_storage[item_index].path
                    test_file_path = os.getcwd() + "\\Test.dat"
                    self.change_path(source_path, test_file_path)

                    process = QProcess(self)
                    process.start(exe_path)
                    process.waitForFinished(-1)
                else:
                    QMessageBox.warning(self, "Warning!", "请先设置本体参数和\n选择气动模型！",
                                                  QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)

                dir = self.make_new_piddir()
                file_list = search_file(os.getcwd())
                remove_file(file_list, dir)
            else:
                QMessageBox.warning(self, "Warning!","请切换到输入文件页面！",
                                              QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
        else:
            QMessageBox.warning(self, "Warning!", "请先导入数据文件！",
                                          QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)

    def click_run_cid(self):
        # print("**********************")
        item_count = self.ui.work_space.item_count
        current_tab = self.ui.show_tabWidget.currentIndex()
        if item_count > 0:
            if current_tab < 0:
                QMessageBox.warning(self, "Warning!", "请先双击工作区数据\n显示在界面中！",
                                              QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
                return None
            if current_tab not in self.index_map:
                QMessageBox.warning(self, "Warning!", "请切换到输入文件页面！",
                                    QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
                return None
            if self.plane_list is not None:
                exe_path = os.getcwd() + "\\AeroCID-RUS-DM.exe"
                file_path = os.getcwd() + "\\AeroCID-in.dat"
                # 生成中间的设置文件并放到和exe同级的目录
                cid_file(self.plane_list, file_path)
                tab_index = self.ui.show_tabWidget.currentIndex()
                item_index = self.index_map[tab_index]
                source_path = self.ui.work_space.item_storage[item_index].path
                test_file_path = os.getcwd() + "\\Test.dat"
                self.change_path(source_path, test_file_path)
                process = QProcess(self)
                process.start(exe_path)
                process.waitForFinished(-1)
                dir = self.make_new_ciddir()
                file_list = search_file(os.getcwd())
                remove_file(file_list, dir)
            else:
                QMessageBox.warning(self, "Warning!", "请先设置飞行器参数！",
                                    QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
        else:
            QMessageBox.warning(self, "Warning!", "请先导入数据文件！",
                                          QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)

    def make_new_piddir(self):
        now_time = time.localtime()
        current_time = time.strftime("%Y%m%d%H%M%S", now_time)
        dir = os.getcwd() + "\\exe_script\\PID_exe\\" + current_time
        os.makedirs(dir, exist_ok=True)
        return dir

    def make_new_ciddir(self):
        now_time = time.localtime()
        current_time = time.strftime("%Y%m%d%H%M%S", now_time)
        dir = os.getcwd() + "\\exe_script\\CID_exe\\" + current_time
        os.makedirs(dir, exist_ok=True)
        return dir

    def change_path(self, source_path, target_path):
        """ 复制文件并改变文件路径 """
        with open(source_path, 'rb') as source_file:
            with open(target_path, 'wb') as target_file:
                target_file.write(source_file.read())

    def display_data(self, data_info):
        tab_widget = MyTableWidget()
        tab_widget.item_name = data_info.name
        tab_widget.setRowCount(data_info.rows)
        tab_widget.setColumnCount(data_info.cols)
        if data_info.have_head:
            tab_widget.setHorizontalHeaderLabels(data_info.head)
        else:
            tab_widget.setHorizontalHeaderLabels([str(i + 1) for i in range(data_info.cols)])
        tab_widget.setEditTriggers(QAbstractItemView.EditTrigger.NoEditTriggers)
        for i in range(data_info.rows):
            for j in range(data_info.cols):
                item = QTableWidgetItem()
                item.setText(str(data_info.data[i][j]))
                item.setTextAlignment(Qt.AlignCenter)
                tab_widget.setItem(i, j, item)
        self.ui.show_tabWidget.addTab(tab_widget, QIcon(':/icon/data.ico'), data_info.name)

    def click_input_file(self):
        dialog = QFileDialog()
        dialog.setFileMode(QFileDialog.AnyFile)  # 设置能打开文件的格式
        dialog.setFilter(QDir.Files)  # 设置为当前的路径
        if dialog.exec_():
            file_path = dialog.selectedFiles()[0]  # 返回选择文件的名字
            openfile = OpenFile()
            data_info = openfile.openfile(file_path)
            data_info.is_displaying = True
            self.ui.work_space.add_item(data_info)
            item_count = self.ui.work_space.item_count
            self.display_data(data_info)
            tab_count = self.ui.show_tabWidget.count() - 1
            self.index_map[tab_count] = item_count - 1          # 保存tab界面和工作区的数据item之间的索引关系
            data_info.display_number = tab_count

    def click_select_model(self):
        item_count = self.ui.work_space.item_count
        if item_count <= 0:
            QMessageBox.warning(self, "Warning!", "请先导入数据文件！",
                                QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
            return None

        selectmodel_win = childWinSelectModel()
        selectmodel_win.show()

        def pd_ok():
            self.model_list = selectmodel_win.mode_list
            checkBox_col = selectmodel_win.checkBox_col.checkState()
            checkBox_row = selectmodel_win.checkBox_row.checkState()
            if checkBox_col != 2:
                self.model_list[0] = [0]*10
                self.model_list[1] = [0]*10
                self.model_list[5] = [0]*10
            if checkBox_row != 2:
                self.model_list[2] = [0]*10
                self.model_list[3] = [0]*10
                self.model_list[4] = [0]*10

            selectmodel_win.close()

        selectmodel_win.pushButton_ok.clicked.connect(pd_ok)
        selectmodel_win.pushButton_cancel.clicked.connect(selectmodel_win.close)
        selectmodel_win.exec_()

    def click_set_param(self):
        item_count = self.ui.work_space.item_count
        if item_count <= 0:
            QMessageBox.warning(self, "Warning!", "请先导入数据文件！",
                                QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
            return None

        setparam_win = childWinSetParam()
        setparam_win.show()

        def pd_ok():
            self.param_list = setparam_win.param_list
            setparam_win.close()

        setparam_win.pushButton_OK.clicked.connect(pd_ok)
        setparam_win.pushButton_Cancel.clicked.connect(setparam_win.close)
        setparam_win.exec_()

    def click_set_plane(self):
        item_count = self.ui.work_space.item_count
        if item_count <= 0:
            QMessageBox.warning(self, "Warning!", "请先导入数据文件！",
                                QMessageBox.Yes | QMessageBox.No, QMessageBox.Yes)
            return None

        setplane_win = childWinSetplane()
        setplane_win.show()

        def pd_ok():
            self.plane_list = setplane_win.plane_list
            setplane_win.close()

        setplane_win.pushButton.clicked.connect(pd_ok)
        setplane_win.pushButton_2.clicked.connect(setplane_win.close)
        setplane_win.exec_()
